// https://thebookofshaders.com/07/?lan=ch
import { 
  Camera,  
  Color,  
  Mesh, 
  PlaneBufferGeometry, 
  Scene, 
  ShaderMaterial, 
  Vector3, 
  WebGLRenderer 
} from "three"
import stats from '../../utils/stats'
import { GUI } from 'dat.gui'

const canvas = document.createElement('canvas')
canvas.style.width = '100vw'
canvas.style.height = '100vh'
canvas.width = window.innerWidth
canvas.height = window.innerHeight
document.body.appendChild(canvas)

const scene = new Scene()
const renderer = new WebGLRenderer({
  antialias: true,
  canvas
})
renderer.autoClearColor = false

const camera = new Camera()
camera.position.z = 1
const plane = new PlaneBufferGeometry(2, 3)

// 片段着色器
const fragmentShader = `
#include <common>

uniform vec2 u_resolution;
uniform float u_time;
uniform int u_size;

#define TWO_PI 6.28318530718

// http://thndl.com/square-shaped-shaders.html

void main() {
  vec2 st = gl_FragCoord.xy / u_resolution.xy;
  st.x *= u_resolution.x / u_resolution.y;

  vec3 color = vec3(0.0);
  float d = 0.0;

  // Remap the space to -1. to 1.
  st = st * 2.0 - 1.0;

  // 定义边的个数
  // int N = 12;

  // Angle and radius from the current pixel
  float a = atan(st.x, st.y) + PI;
  float r = TWO_PI / float(u_size);

  // Shaping function that modulate the distance
  d = cos(floor(0.5+a/r)* r-a)*length(st);

  color = vec3(1.0 - smoothstep(0.4, 0.401, d));

  gl_FragColor = vec4(color, 1.0);
}
`

const uniforms = {
  u_time: { value: 0 },
  u_resolution: { value: new Vector3() },
  u_size: { value: 3 }
}
const material = new ShaderMaterial({
  fragmentShader,
  uniforms
})
scene.add(new Mesh(plane, material))

const controls = {
  size: 3
}
const gui = new GUI()
gui.add(controls, 'size', 3, 100, 1)

function render(time: number) {
  stats.update()
  // 转化成秒
  time *= 0.001

  uniforms.u_time.value = time
  const canvas = renderer.domElement
  uniforms.u_resolution.value.set(canvas.width, canvas.height, 1)
  uniforms.u_size.value = controls.size

  renderer.render(scene, camera)

  requestAnimationFrame(render)
}

requestAnimationFrame(render)